﻿using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows;
using LFSRecord2.Events;
using LFSRecord2.Model;
using LFSRecord2.Structures;
using Microsoft.Practices.Composite.Presentation.Events;

namespace LFSRecord2.ViewModel
{
    public class ViewportViewModel : ViewModelBase
    {
        public ObservableCollection<CompLayerBase> AllLayers { get; private set; }

        private bool _camMovesCurrentValues = true;
        public bool CamMovesCurrentValues
        {
            get { return _camMovesCurrentValues; }
            set
            {
                _camMovesCurrentValues = value;
                OnPropertyChanged("CamMovesCurrentValues");
            }
        }

        public static readonly DependencyProperty CurrentTrackProperty = DependencyProperty.Register(
            "CurrentTrack",
            typeof(string),
            typeof(ViewportViewModel)
        );
        public string CurrentTrack
        {
            get { return (string)GetValue(CurrentTrackProperty); }
            set { SetValue(CurrentTrackProperty, value); }
        }

        public static readonly DependencyProperty WorldCamProperty = DependencyProperty.Register(
            "WorldCam",
            typeof(LfsCamera),
            typeof(ViewportViewModel),
            new PropertyMetadata(new LfsCamera())
        );
        public LfsCamera WorldCam
        {
            get { return (LfsCamera)GetValue(WorldCamProperty); }
            set
            {
                SetValue(WorldCamProperty, value);
                OnPropertyChanged("WorldCam");

                if (_camMovesCurrentValues)
                    LfsRecordController.project.SetActiveCameraValues(WorldCam, true);
            }
        }

        public static readonly DependencyProperty CurrentFrameProperty = DependencyProperty.Register(
            "CurrentFrame",
            typeof(int),
            typeof(ViewportViewModel),
            new PropertyMetadata(0)
        );
        public int CurrentFrame
        {
            get { return (int)GetValue(CurrentFrameProperty); }
            set { SetValue(CurrentFrameProperty, value); }
        }

        public ViewportViewModel()
        {
            AllLayers = LfsRecordController.project.Layers;
            //AllLayers = new ObservableCollection<CompLayerBase>(_allLayers);

            //WorldCam = new LfsCamera(LfsRecordController.project.GetActiveCameraType());
            //CurrentFrame = 0;

            PropertyChanged += OnMyWorldCamChanged;
            ServicesFactory.EventService.GetEvent<WorldCamChangedEvent>().Subscribe(OnWorldCamChanged);

            ServicesFactory.EventService.GetEvent<FrameIndexChangedEvent>().Subscribe(OnCurrentFrameChanged, ThreadOption.UIThread);

            ServicesFactory.EventService.GetEvent<TrackChangedEvent>().Subscribe(OnTrackChanged, ThreadOption.UIThread);
        }

        public void OnTrackChanged(string trackName)
        {
            CurrentTrack = trackName;
        }

        private void OnMyWorldCamChanged(object sender, PropertyChangedEventArgs e)
        {
            //if (!_camMovesCurrentValues)
                ServicesFactory.EventService.GetEvent<WorldCamChangedEvent>().Publish(new WorldCamChangedEventArgs() { Sender = this, Cam = WorldCam });
            
            //Debug.WriteLine("ViewportView cam changed internally");
        }

        private void OnWorldCamChanged(WorldCamChangedEventArgs e)
        {
            if (e.Sender == null || e.Sender.GetType() != typeof(ViewportViewModel))
                SetValue(WorldCamProperty, e.Cam);
            //Debug.WriteLine("ViewportView cam changed externally - " + e.Cam.X);
        }

        private void OnCurrentFrameChanged(FrameIndexChangedEventArgs e)
        {
            if (e.Sender == null || e.Sender.GetType() != typeof(ViewportViewModel))
                SetValue(CurrentFrameProperty, e.NewFrameIndex);
        }
    }
}
